package com.cuotigou.service.impl;


import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.cuotigou.config.ConfigUtils;
import com.cuotigou.config.PayConfig;
import com.cuotigou.mapper.SRechargeListMapper;
import com.cuotigou.mapper.SUserChargeMapper;
import com.cuotigou.mapper.SUserMapper;
import com.cuotigou.pojo.SRechargeList;
import com.cuotigou.pojo.SUser;
import com.cuotigou.pojo.SUserCharge;
import com.cuotigou.pojo.WeixinPayParam;
import com.cuotigou.service.PayService;
import com.cuotigou.util.*;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.cuotigou.config.PayConfig.ALIPAY_APPID;
import static com.cuotigou.config.PayConfig.ALIPAY_PRIVWER_KEY;
import static com.cuotigou.config.PayConfig.ALIPAY_PUBLIC_KEY;

/**
 * Created by Administrator on 2019/1/16.
 */
@Service
@Transactional
public class PayServiceImpl implements PayService {

    private static  final Logger Log = LoggerFactory.getLogger(PayServiceImpl.class);

    @Autowired
    private SRechargeListMapper sRechargeListMapper;
    @Autowired
    private SUserChargeMapper sUserChargeMapper;
    @Autowired
    private SUserMapper sUserMapper;

    @Override
    public ObjectResult aliPay(XMLBean xmlBean) throws IOException {
        String userId = CommonUtils.decToken(xmlBean.getToken());
        SRechargeList sRechargeList = sRechargeListMapper.selectByPrimaryKey(Integer.parseInt(xmlBean.getId()));
        if(sRechargeList == null){
            return ObjectResult.build("0","不存在的内容");
        }

        //生成订单号
        String orderNo = CommonUtils.getRechargeNo("10001");

        SUserCharge sUserCharge = new SUserCharge();
        sUserCharge.setOrderNo(orderNo);
        sUserCharge.setUserId(Long.parseLong(userId));
        sUserCharge.setValue(sRechargeList.getCost());
        sUserCharge.setStatus("1");
        sUserCharge.setAddTime(new Date());
        sUserCharge.setModifyTime(new Date());
        sUserCharge.setRemark("支付宝购买vip");
        sUserCharge.setPayType(1);
        sUserCharge.setRechargeId(sRechargeList.getId());
        sUserChargeMapper.insertSelective(sUserCharge);

        //实例化客户端
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", ALIPAY_APPID
                , FileUtil.fileRead(ALIPAY_PRIVWER_KEY), "json", "utf-8", FileUtil.fileRead(ALIPAY_PUBLIC_KEY), "RSA2");
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody("");
        model.setSubject("错题狗-会员充值");
        model.setOutTradeNo(orderNo);
        model.setTimeoutExpress("30m");
        model.setTotalAmount(sRechargeList.getCost().toString());
        model.setProductCode("QUICK_MSECURITY_PAY");
        request.setBizModel(model);
        request.setNotifyUrl(ConfigUtils.SYS_URL+"pay/aliPayNotify");
        try {
            //这里和普通的接口调用不同，使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            System.out.println(response.getBody());//就是orderString 可以直接给客户端请求，无需再做处理。
            return ObjectResult.build("1","创建订单成功",response.getBody());
        } catch (AlipayApiException e) {
            ExceptionUtil.logError(e,Log);
            return ObjectResult.build("0","创建订单失败");
        }
    }

    @Override
    public void aliPayNotify(Map<String, String> map) {
        String out_trade_no = map.get("out_trade_no");
        SUserCharge sUserCharge = sUserChargeMapper.selectByOrderNo(out_trade_no);
        if (sUserCharge == null){
            Log.info("---------------订单错误-----------------");
            return;
        }

        //修改订单状态
        sUserCharge.setStatus("2");
        sUserChargeMapper.updateByPrimaryKeySelective(sUserCharge);

        SUser sUser = sUserMapper.selectByPrimaryKey(sUserCharge.getUserId());
        Date vipTime = sUser.getExpireTime();

        //修改vip时间
        SRechargeList sRechargeList = sRechargeListMapper.selectByPrimaryKey(sUserCharge.getRechargeId());
        //未购买过vip或已过期直接从当前时间算起
        if (vipTime==null ||vipTime.compareTo(new Date())<0){
            vipTime = DateUtil.addDateDay(new Date(), sRechargeList.getRecharge().intValue());
        }else {
            //未过期从过期时间算起
            vipTime = DateUtil.addDateDay(vipTime, sRechargeList.getRecharge().intValue());
        }
        sUser.setExpireTime(vipTime);
        sUser.setIsVip(1);
        sUserMapper.updateByPrimaryKeySelective(sUser);

        Log.info("---------------vip购买完成-----------------");

    }

    @Override
    public ObjectResult weixin(XMLBean xmlBean,String ip) {

        String userId = CommonUtils.decToken(xmlBean.getToken());
        SRechargeList sRechargeList = sRechargeListMapper.selectByPrimaryKey(Integer.parseInt(xmlBean.getId()));
        if(sRechargeList == null){
            return ObjectResult.build("0","不存在的内容");
        }

        // 1.微信支付参数
        //微信开放平台审核通过的应用APPID
        String appid = PayConfig.WEIXIN_APPID;
        //微信支付分配的商户号
        String mch_id = PayConfig.MCH_ID;
        //通知地址
        String notify_url = ConfigUtils.SYS_URL+"pay/weixinNotify";
        //key为商户平台设置的密钥key
        String appKey = PayConfig.APP_KEY;

        String partnerid = PayConfig.MCH_ID;

        String nonce_str = CommonUtils.getRandomString(12);
        WeixinPayParam wxpp = new WeixinPayParam();
        Map<String, String> params = new HashMap<String, String>();
        params.put("appid", appid);
        params.put("mch_id", mch_id);
        try {
            //生成订单号
            String orderNo = CommonUtils.getRechargeNo("10001");

            SUserCharge sUserCharge = new SUserCharge();
            sUserCharge.setOrderNo(orderNo);
            sUserCharge.setUserId(Long.parseLong(userId));
            sUserCharge.setValue(sRechargeList.getCost());
            sUserCharge.setStatus("1");
            sUserCharge.setAddTime(new Date());
            sUserCharge.setModifyTime(new Date());
            sUserCharge.setRemark("微信购买vip");
            sUserCharge.setPayType(2);
            sUserCharge.setRechargeId(sRechargeList.getId());
            sUserChargeMapper.insertSelective(sUserCharge);
            params.put("body", "cuotigou");
            params.put("out_trade_no", orderNo);

            String strAmt = sRechargeList.getCost().multiply(new BigDecimal(100)).setScale(0).toString();

            params.put("total_fee", strAmt);
            params.put("spbill_create_ip", ip);
            params.put("trade_type", "APP");
            params.put("nonce_str", nonce_str);
            params.put("notify_url", notify_url);

            String sign = PaymentKit.createSign(params, appKey);
            params.put("sign", sign);


            String xml = PaymentKit.toXml(params);

            Log.info("请求参数:" + xml);
            String returnXml = null;
            try {
                returnXml = HttpUtils.executePostMethod(
                        "https://api.mch.weixin.qq.com/pay/unifiedorder",
                        "UTF-8", xml);
            } catch (IOException e) {
                e.printStackTrace();
            }
            Log.info("返回结果:" + returnXml);
            ParamsUtil paramsUtil = new ParamsUtil();
            String retCode = paramsUtil.getValue("result_code",
                    returnXml);
            String returnCode = paramsUtil.getValue("return_code",
                    returnXml);// return_code
            if (StringUtils.contains(returnCode, "FAIL")) {

                return ObjectResult.build("0","使用微信下单失败");

            }
            if (StringUtils.contains(retCode, "SUCCESS")) {
                String payIdStr = paramsUtil.getValue("prepay_id",
                        returnXml);
                String payId = payIdStr.substring(9, 45);
                String signC = "";

                Map<String, String> payParams = new HashMap<String, String>();
                payParams.put("prepayid", payId);
                wxpp.setPrepayId(payId);
                payParams.put("package", "Sign=WXPay");
                wxpp.setWepackage("Sign=WXPay");
                String nonce_strB = CommonUtils.getRandomString(12);
                wxpp.setNonceStr(nonce_strB);
                payParams.put("noncestr", nonce_strB);
                String timeStamp = Long.toString(System
                        .currentTimeMillis() / 1000);
                wxpp.setTimeStamp(timeStamp);
                payParams.put("timestamp", timeStamp);
                wxpp.setAppId(appid);
                payParams.put("appid", appid);
                payParams.put("partnerid", partnerid);
                signC = PaymentKit.createSign(payParams, appKey);
                wxpp.setPaySign(signC);
                wxpp.setPartnerId(partnerid);
                // 2.订单相关参数
                wxpp.setOrderNo(orderNo);
                wxpp.setGoodTitle("错题狗-会员充值");
                wxpp.setAllOrderAmount(sUserCharge.getValue());
            } else {
                return ObjectResult.build("0","使用微信下单失败");
            }
        } catch (RuntimeException e) {
            ExceptionUtil.logError(e,Log);
            return ObjectResult.build("0","创建订单失败");
        }

        return ObjectResult.build("1","成功",wxpp);
    }

    @Override
    public ObjectResult applePay(String userId, String productId) {
        SRechargeList sRechargeList = sRechargeListMapper.selectByProductId(productId);
        if (sRechargeList == null){
            return ObjectResult.build("0","找不到商品");
        }

        try {
            //添加订单
            String orderNo = CommonUtils.getRechargeNo("10003");
            SUserCharge sUserCharge = new SUserCharge();
            sUserCharge.setOrderNo(orderNo);
            sUserCharge.setUserId(Long.parseLong(userId));
            sUserCharge.setValue(sRechargeList.getCost());
            sUserCharge.setStatus("2");
            sUserCharge.setAddTime(new Date());
            sUserCharge.setModifyTime(new Date());
            sUserCharge.setRemark("applePay购买vip");
            sUserCharge.setPayType(3);
            sUserCharge.setRechargeId(sRechargeList.getId());
            sUserChargeMapper.insertSelective(sUserCharge);

            //修改vip时间
            SUser sUser = sUserMapper.selectByPrimaryKey(sUserCharge.getUserId());
            Date vipTime = sUser.getExpireTime();
            //未购买过vip或已过期直接从当前时间算起
            if (vipTime == null || vipTime.compareTo(new Date()) < 0) {
                vipTime = DateUtil.addDateDay(new Date(), sRechargeList.getRecharge().intValue());
            } else {
                //未过期从过期时间算起
                vipTime = DateUtil.addDateDay(vipTime, sRechargeList.getRecharge().intValue());
            }
            sUser.setExpireTime(vipTime);
            sUser.setIsVip(1);
            sUserMapper.updateByPrimaryKeySelective(sUser);
        }catch (RuntimeException e){
            ExceptionUtil.logError(e,Log);
            return ObjectResult.build("0","vip购买失败");
        }

        return ObjectResult.build("1","vip购买成功");
    }
}
